Refinements in the Search API

Learn how we can evolve the search API by adding new features.

The purpose of this lesson is to learn how we can enhance the functionality of the search API by adding a new feature. Our API already supports some basic features. For example, sorting improves the user experience, whereas pagination reduces unnecessary load on the network. However, we need a feature that allows our users to refine the search criteria to find specific data.

To achieve that, we’ll need to add the filtering functionality along with appropriate versioning.

  • Filtering: This section introduces filtering, its types, and discusses how clients can interact with the search service to request filtering.

  • Versioning: This section focuses on versioning and discusses the versioning semantics required to support filtering.

Let's start with how to add filtering to the existing design of the search API.

Filtering#

Filtering is the process of restricting search results based on the user's requirements or criteria. It is a crucial ability in the search feature. For example, it’s possible to filter search results to return only images and videos.

There are two types of filtering:

  • Simple filter: In simple filtering, the search query filters results on the basis of a single entity. For example, if the user wants to see only "data structure" courses of the "intermediate" level, the query string for this search is set to "data structure," whereas the filter value is set to "intermediate.”

  • Complex filter: In complex filtering, the search query filters results on the basis of a defined range. For example, if the user wants to see courses in a certain price range (for instance, $20 to $30), then the search API should return the courses in the specified price range.

Let's look at the details of each filtering technique.

Simple filters#

Simple filters require us to provide attributes to the API based on the type of filtering that is performed. For example, on educational websites, we have multiple attributes, like course level, author, and so forth. If we want to filter data on the basis of the course level, then the client can send a request using the following URL:

The filter parameter tells the search service that filtering needs to be performed instead of the simple search. The request is forwarded to the search system, which returns only intermediate-level Java courses to our search API. The API may further apply sorting and/or pagination functions if required before sending the data back to the client.

Performing filtering before the searcher returns the results is efficient because it will take a shorter time to respond to the client, as shown in the illustration below. In the example where we search for the Java string, we’ll apply the Intermediate filter on search and then return the final results to the search request handler server.

Returning results before applying filtering (left) and returning results after applying filtering (right)
Returning results before applying filtering (left) and returning results after applying filtering (right)

As we can see on the left side of the illustration, transferring a large number of results from the searcher to the API takes more time. Simple filtering may take negligible time to process but supplies much more concise results to the user.

Complex filters#

Complex filters are mostly based on ranges to refine search results. Defining the ranges in the URL makes it different from simple filtering. The complex filters require three elements, such as field, filter, and field value. The following table demonstrates the example of these elements.

Example Elements

Elements

Examples

Field

Date, price

Filter

Less than or equal to (lte), greater than equal to (gte)

Field value

2022-10-03, $39

Let's see how we can pass these elements as parameters into our search API.

Calling this endpoint retrieves all Java courses priced between $29 and $32. We can see that the filter is defined as price=gte:$29, which divides into three elements: price as a field, gte as a filter, and $29 as a field value. The response time of complex filters is a little high compared to simple filters because the back-end services take time to identify the matched records.

Now that we looked at the details of filtering and how clients can request search queries with the filters. Let's see how the consumer of the API will be able to use them. For this purpose, we will make use of the API versioning concept.

The need for versioning#

Adding new capabilities to the API (requiring the client to send more information in the request and asking the server to parse that information) might cause issues over time, so we need version control in our API to manage these changes. We can merge changes by performing major versioning or minor versioning. Here, we treat the features above as minor feature updates because new functionality (filtering) is optional and does not affect the existing functionality of our API.

The base URL for the new version of our search API can ideally be as follows:

The base URL for search API
The base URL for search API

Regarding the version number mentioned above, we update only the minor version for filtering functionality because we are only adding a new feature support in our API. Since it won't result in breaking client's applications, we update to v1.1 instead of v2.0.

The updated base URL for the search’s API endpoints is as follows:

GET /v1.1/search?query={string}&filter={value}&field={filter}:{value}&field={filter}:{value} HTTP/1.1
GET /v1.1/search?query={string}&filter={value}&filterfield={value} HTTP/1.1
Complex
Simple
Ads
Recomendation
Filter
Search
Operations
Operations of the search API and their corresponding endpoints

We shift our previous features to the new version by redirecting the requests from v1.0 to v1.1, keeping the new version backward compatible.

Quiz

Q

Let’s suppose the user wants to obtain a list of records in ISO format (YYYY-MM-DD) from 2022-02-21 to 2022-03-21 and get the most recent record at the top of the list.

Which parameter should the user pass to the API endpoint to get the results in the desired order?

Your Answer
A)

query=record, filter=Yes, date=gte:2022-02-21, date=lte:2022-03-21

Correct Answer
B)

query=record, filter=Yes, date=gte:2022-02-21, date=lte:2022-03-21, sort=date, order=descending

Explanation

This option is correct because it contains all the required parameters.

C)

query=record, filter=Yes, date=gte:2022-02-21, date=lte:2022-03-21, sort=descending

D)

None of the above

API Model for Search Service

Search API Design Evaluation and Latency Budget